using System.Collections;
using System.Collections.Generic;
using System.IO;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Networking;
/// <summary>
/// 
/// ��Ϸ���߼�
/// 
/// </summary>
public enum EGameStatus
{
    NONE,
    START,
    GAMING,
    GAMEOVER
}

public class Game : MonoBehaviour
{

    [SerializeField]
    private Transform toysRoot;

    private List<string> curLevelData = new();

    public Dictionary<string, List<float>> posMap = new();
    /// <summary>
    /// 消除的个数与分数的对应关系
    /// </summary>
    /// <typeparam name="string"></typeparam>
    /// <typeparam name="float"></typeparam>
    /// <returns></returns>
    public Dictionary<string,float> scoreTime = new Dictionary<string, float>();

    private List<Transform> allToys = new();

    private PlayerData playerData = null;

    /// <summary>
    /// 定义一个委托监听关卡配置问价加载完毕
    /// </summary>
    public delegate void LoadLevelConfigCompleteDelegate();

    private bool initToyOver = false;

    private int _score = 0;

    public int Score
    {
        get
        {
            return _score;
        }
        set
        {
            _score = value;
            // TODO 更新分数
            UpdatePlayerData(_score);
        }
    }

    public void UpdatePlayerData(int? score = null,int? level = null) {
        if(playerData == null) {
            Debug.Log("playerData is null");
            return;
        }
        if(score.HasValue) {
            playerData.maxScore = score.Value;
        }
        if(level.HasValue) {
            playerData.maxLevel = level.Value;
        }
        GameManager.Instance().storageManager.UpdateDataToStore(GameConsts.storeKey,playerData);
    }

    private EGameStatus _gameStatus = EGameStatus.NONE;
    public EGameStatus gameStatus
    {
        get { return _gameStatus; }
        set
        {
            if(value == _gameStatus) return;
            _gameStatus = value;
            switch (value)
            {
                case EGameStatus.START:
                    GameManager.Instance().topUI.GameTotalTime = 60;
                    GameManager.Instance().topUI.StartTimeCountdown();
                    break;
                case EGameStatus.GAMING:
                    break;
                case EGameStatus.GAMEOVER:
                    UnityEngine.Debug.LogWarning($"游戏结束了");
                    bool isWin = GameManager.Instance().slotManagers.IsWin() && CheckAllToyLosted();
                    GameManager.Instance().topUI.Countdown = false;
                    ShowGameResult(isWin);
                    break;
            }
        }
    }

    /// <summary>
    /// 显示游戏结果
    /// </summary>
    /// <param name="isWin"></param>
    public void ShowGameResult(bool isWin) {
        GameManager.Instance().topUI.ShowResult(isWin);
    }

    private void Awake()
    {
        AndroidUtils.Vibrate(200);
        UnityEngine.Debug.Log("Game Awake");
        GameManager.Instance().game = this;
        GameManager.Instance().levelManager.Init();

        StartCoroutine(ResourcesMaanger.Instance.LoadConfig($"Config/posMap.json", EConfigType.POS, LoadPosMapOver));
        StartCoroutine(ResourcesMaanger.Instance.LoadConfig($"Config/score.json",EConfigType.SCORE,LoadScoreOver));

        PlayerData tempData = GameManager.Instance().storageManager.GetDataFromStore(GameConsts.storeKey);
        Debug.Log("tempData is " + tempData);
        if(tempData == null) {
            playerData = new PlayerData();
            UpdatePlayerData(Score,GameManager.Instance().levelManager.CurLevel);
        } else {
            playerData = tempData;
            GameManager.Instance().levelManager.CurLevel = playerData.maxLevel;
        }
    }

    private void LevelLoadOver()
    {
        if (!initToyOver)
        {
            InitAllToy();
            gameStatus = EGameStatus.START;
        }
    }

    public void RestartGame() {
        initToyOver = false;
        Score = 0;
        allToys.Clear();
        curLevelData.Clear();

        GameManager.Instance().slotManagers.Clear();
        foreach(Transform child in toysRoot) {
            Destroy(child.gameObject);
        }
        GameManager.Instance().uiManager.Restart();
        GameManager.Instance().topUI.ResetUI();
        StartCoroutine(LoadLevelConfig(LevelLoadOver));
    }

    private void LoadPosMapOver(IConfigData data)
    {
        if (data == null)
        {
            UnityEngine.Debug.Log("data is null");
            return;
        }
        PosConfig config = (PosConfig)data;
        posMap = config.list;

        List<float> flots = posMap.GetValueOrDefault("Apple_0 #1218");
        UnityEngine.Debug.Log("flots is " + flots);
    }

    private void LoadScoreOver(IConfigData data) {
        if(data == null) return;
        ScoreConfig scoreConfig = (ScoreConfig)data;
        
        Dictionary<string,float> config =  scoreConfig.scoreMap;
        scoreTime = config;
    }

    /// <summary>
    /// 根据当前倍数来获得连消累积时长
    /// </summary>
    /// <param name="ratio"></param>
    /// <returns></returns>
    public float GetTimeByRatio(int ratio) {
        if(scoreTime == null) return 10f;
        return scoreTime.GetValueOrDefault(ratio.ToString());
    }

    IEnumerator LoadLevelConfig(LoadLevelConfigCompleteDelegate onComplete)
    {
        UnityEngine.Debug.Log($"加载关卡配置文件: {GameManager.Instance().levelManager.CurLevel}");
        int level = GameManager.Instance().levelManager.CurLevel;
        if(level >= GameConsts.maxLevel) {
            level = GameConsts.maxLevel;
            GameManager.Instance().levelManager.CurLevel = level;
        }

        string path = Path.Combine(Application.streamingAssetsPath, $"Levels/level{level}.json");
        if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.WebGLPlayer)
        {
            UnityEngine.Debug.Log($"in Android or WebGL path is {path}");

            UnityWebRequest www = UnityWebRequest.Get(path);
            yield return www.SendWebRequest();
            UnityEngine.Debug.Log($"www.result is {www.result}");
            if (www.result == UnityWebRequest.Result.Success)
            {
                string json = www.downloadHandler.text;
                UnityEngine.Debug.Log($"json is {json}");
                ParseJson(json);
            }
            else
            {
                UnityEngine.Debug.LogWarning("error is " + www.error);
            }
        }
        else
        {
            if (File.Exists(path))
            {
                string json = File.ReadAllText(path);
                ParseJson(json);
            }
            else
            {
                UnityEngine.Debug.Log("Config file not found at " + path);
            }
        }
        onComplete.Invoke();
    }

    void ParseJson(string json)
    {
        LevelConfig toyTypes = JsonUtility.FromJson<LevelConfig>(json);
        UnityEngine.Debug.Log($"toyTypes  is {toyTypes}");

        if (toyTypes != null && toyTypes.toys != null)
        {
            UnityEngine.Debug.Log($"toyTypes.toys is {toyTypes.toys}");

            foreach (var toyItem in toyTypes.toys)
            {
                for (int i = 0; i < GameConsts.clearCount; i++)
                {
                    curLevelData.Add(toyItem);
                }
            }
        }
        Shuffle(curLevelData);
    }

    public static void Shuffle(List<string> list)
    {
        System.Random rng = new();
        int n = list.Count;
        while (n > 1)
        {
            n--;
            int k = rng.Next(n + 1);
            (list[n], list[k]) = (list[k], list[n]);
        }
    }


    // Start is called before the first frame update
    void Start()
    {
        GameManager.Instance().envManagers.Init();
        GameManager.Instance().topUI.ResetUI();
        StartCoroutine(LoadLevelConfig(LevelLoadOver));
    }

    private void InitAllToy()
    {
        RealInitToys();
    }

    private void RealInitToys()
    {
        float startY = 500f;
        float spaceY = 100f;

        float minX = GameManager.Instance().envManagers.minX;
        float maxX = GameManager.Instance().envManagers.maxX;
        float minZ = GameManager.Instance().envManagers.minZ;
        float maxZ = GameManager.Instance().envManagers.maxZ;

        UnityEngine.Debug.Log($"minZ is {minZ} and maxZ is {maxZ}");


        int size = 4;
        if(curLevelData.Count >= 4 && curLevelData.Count < 9) {
            size = 2;
        } else if(curLevelData.Count <= 9 && curLevelData.Count > 4) {
            size = 3;
        } else if(curLevelData.Count <= 16 && curLevelData.Count > 9) {
            size = 4;
        } else {
            size = 5;
        }

        float gridWidth = (maxX - minX) / size;
        float gridHeight = (maxZ - 1 - (minZ + 1)) / size;

        int layerOpacity = size * size;
        float gridStartX = minX + gridWidth / 2;
        float gridStartZ = minZ + gridHeight / 2;

        UnityEngine.Debug.Log("layerOpacity is " + layerOpacity);

        // һ��36��
        Vector3[] grids = new Vector3[layerOpacity];

        int start = 0;
        for (int i = 0; i < size; i++)
        {
            for (int j = 0; j < size; j++)
            {
                grids[start] = new Vector3(gridStartX + gridWidth * j, startY, gridStartZ + gridHeight * i);
                start++;
            }
        }

        UnityEngine.Debug.Log($"curLevelData's count is {curLevelData.Count} ");
        int mSlice = 16;
        if (curLevelData.Count > 0)
        {
            UnityEngine.Debug.Log("开始动态加载预制件");
            int i = 0;
            curLevelData.ForEach(x =>
            {
                string itemP = $"Prefabs/{x}";
                UnityEngine.Debug.LogWarning($"加载{x}物体");
                UnityEngine.Object obj = Resources.Load(itemP);
                if (obj == null)
                {
                    UnityEngine.Debug.LogWarning("Failed to load resource: " + itemP);
                    return;
                }


                int pos = i % (layerOpacity);
                int layer = i / (layerOpacity);

                Vector3 itemPos = grids[pos];
                itemPos.x += UnityEngine.Random.Range(-gridWidth / mSlice, gridWidth / mSlice) * layer;
                itemPos.z += UnityEngine.Random.Range(-gridHeight / mSlice, gridHeight / mSlice) * layer;
                itemPos.y += layer * spaceY;

                if (obj)
                {
                    UnityEngine.Debug.LogWarning($"开始初始化物体{x}");
                    var toy = Instantiate(obj, itemPos, Quaternion.identity, toysRoot);
                    Toy toyCompo = toy.GetComponent<Toy>();
                    allToys.Add(toyCompo.transform);
                    toyCompo.ToyName = x;
                    UnityEngine.Debug.LogWarning($"{x}加入场景");
                }
                else
                {
                    UnityEngine.Debug.LogWarning($"加载{x}失败！！！");
                }

                i++;
            });
            initToyOver = true;
        }
    }

    /// <summary>
    /// 检查所有的玩具是否消失
    /// </summary>
    /// <returns></returns>
    public bool CheckAllToyLosted() {
        UnityEngine.Debug.Log($"堆里面的玩具数量：{allToys.Count}");
        return allToys.Count == 0;
    }

    public void SubToy(Transform ts) {
        if(ts == null) return;
        allToys.Remove(ts);
    }

    public static void Log(string info)
    {
        UnityEngine.Debug.Log(info);
    }
}
